#include "CDashboard_DCB.h"

#include <QEventLoop>
#include <QHBoxLayout>
#include <QLabel>
#include <QTimer>

#include "core/CDeviceManager.h"
#include "core/logger.h"
#include "view/custom/CustomBoxView.h"

CDashboard_DCB::CDashboard_DCB(QWidget *parent) :
    QWidget(parent)
{
    ui.setupUi(this);

    // connect
    connect(ui.view_lockers, &CCustomBoxView::boxClicked,
            this, &CDashboard_DCB::event_box_clicked);

    // default layout
    on_combo_layout_currentIndexChanged(0);
}

CDashboard_DCB::~CDashboard_DCB()
{
}

void CDashboard_DCB::ResetData()
{
}

void CDashboard_DCB::reset_lockers_layout(int max_row, int max_col)
{
    ui.view_lockers->SetLayout(max_row, max_col);
}

QString CDashboard_DCB::get_device_id()
{
    return property("deviceid").toString();
}

void CDashboard_DCB::open_lockers(int begno, int endno)
{
    if (begno > endno)
    {
        return;
    }

    auto deviceid = get_device_id().toStdString();
    auto device = CDeviceManager::Instance().GetDoorControlBoard(deviceid);
    if (device == nullptr)
    {
        MSG(ERROR) << tr("Operation failed, invalid device object");
        return;
    }

    for (int i = begno; i <= endno; ++i)
    {
        auto ret = device->OpenLocker(i);
        QString msg = tr("Open box, deviceid: %1 id: %2, result: %3")
                          .arg(deviceid.c_str())
                          .arg(i)
                          .arg(CRet(ret).string());
        MSG(INFO) << msg;
        QEventLoop el;
        QTimer::singleShot(500, &el, &QEventLoop::quit);
        el.exec();
    }
}

void CDashboard_DCB::on_combo_layout_currentIndexChanged(int index)
{
    int count = 0;
    switch (index)
    {
        case 0:
            reset_lockers_layout(5, 2);
            count = 5 * 2;
            break;
        case 1:
            reset_lockers_layout(4, 6);
            count = 4 * 6;
            break;
        case 2:
            reset_lockers_layout(5, 8);
            count = 5 * 8;
            break;
        case 3:
            reset_lockers_layout(16, 16);
            count = 16 * 16;
            break;
        default:
            count = 0;
            break;
    }

    ui.combo_begno->clear();
    ui.combo_endno->clear();
    for (int i = 1; i <= count; ++i)
    {
        ui.combo_begno->addItem(QString::number(i));
        ui.combo_endno->addItem(QString::number(i));
    }
    ui.combo_begno->setCurrentIndex(0);
    ui.combo_endno->setCurrentIndex(0);
}

void CDashboard_DCB::on_btn_openbox_clicked()
{
    int begno = ui.combo_begno->currentIndex() + 1;
    int endno = ui.combo_endno->currentIndex() + 1;

    open_lockers(begno, endno);
}

void CDashboard_DCB::on_btn_openall_clicked()
{
    int count = 0;
    switch (ui.combo_layout->currentIndex())
    {
        case 0:
            count = 5 * 2;
            break;
        case 1:
            count = 4 * 6;
            break;
        case 2:
            count = 5 * 8;
            break;
        case 3:
            count = 16 * 16;
            break;
        default:
            return;
    }

    open_lockers(1, count);
}

void CDashboard_DCB::on_btn_doorstatus_clicked()
{
    auto deviceid = get_device_id().toStdString();
    auto device = CDeviceManager::Instance().GetDoorControlBoard(deviceid);
    if (device == nullptr)
    {
        MSG(ERROR) << tr("Operation failed, invalid device object");
        return;
    }

    unsigned char status[256] {0x00};
    size_t status_len = 256;
    auto ret = device->GetDoorStatus(status, status_len);
    if (ret != zl::zlbase::ZLResult_Success)
    {
        MSG(ERROR) << tr("Operation failed, error code: %1").arg(CRet(ret).string());
        return;
    }

    // update status
    for (size_t i = 0; i < status_len; ++i)
    {
        ui.view_lockers->SetData(i, CCustomBoxCell::EDataRole_Door, status[i]);
    }
}

void CDashboard_DCB::on_btn_itemstatus_clicked()
{
    auto deviceid = get_device_id().toStdString();
    auto device = CDeviceManager::Instance().GetDoorControlBoard(deviceid);
    if (device == nullptr)
    {
        MSG(ERROR) << tr("Operation failed, invalid device object");
        return;
    }

    unsigned char status[256] {0x00};
    size_t status_len = 256;
    auto ret = device->GetItemStatus(status, status_len);
    if (ret != zl::zlbase::ZLResult_Success)
    {
        MSG(ERROR) << tr("Operation failed, error code: %1").arg(CRet(ret).string());
        return;
    }

    // update status
    for (size_t i = 0; i < status_len; ++i)
    {
        ui.view_lockers->SetData(i, CCustomBoxCell::EDataRole_Item, status[i]);
    }
}

void CDashboard_DCB::event_box_clicked(int id)
{
    ui.combo_begno->setCurrentText(QString::number(id));
    ui.combo_endno->setCurrentText(QString::number(id));
}